/*
 * Copyright 2006, 2008 by Brian Dominy <brian@oddchange.com>
 *
 * This file is part of FreeWPC.
 *
 * FreeWPC is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * FreeWPC is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with FreeWPC; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */


/* This system utility manipulates lamplists. */

#define MAX_LAMPS 64

typedef unsigned char U8, task_ticks_t;

/* System includes */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* Target includes */
#include <sys/lamp.h>
#include <mach/lamp.h>

struct lamplist {
	U8 lamps[MAX_LAMPS];
	int count;
};


struct lamplist *
lamplist_allocate (void)
{
	struct lamplist *lms = malloc (sizeof (struct lamplist));
	lms->count = 0;
}


void
lamplist_free (struct lamplist *lms)
{
	free (lms);
}


void
lamplist_dump (struct lamplist *lms)
{
	int count = lms->count;
	const U8 *lamps = lms->lamps;

	printf ("[ ");
	while (count-- > 0)
		printf ("%02X ", *lamps++);		
	printf ("]\n");
}


void
lamplist_fill (struct lamplist *lms, const U8 *lamps, int count)
{
	memcpy (lms->lamps, lamps, count);
	lms->count = count;
}

void
lamplist_reverse (struct lamplist *lms)
{
}

void
lamplist_add (struct lamplist *lms1, struct lamplist *lms2)
{
}

void
lamplist_subtract (struct lamplist *lms1, struct lamplist *lms2)
{
}

void
lamplist_and (struct lamplist *lms1, struct lamplist *lms2)
{
}

void
lamplist_or (struct lamplist *lms1, struct lamplist *lms2)
{
}

void
lamplist_randomize (struct lamplist *lms, int count)
{
	int i;
	for (i=0; i < lms->count * 8 * count; i++)
	{
		int j = ((rand () * 1.0) / RAND_MAX) * lms->count;
		int k = ((rand () * 1.0) / RAND_MAX) * lms->count;
		U8 temp = lms->lamps[j];
		lms->lamps[j] = lms->lamps[k];
		lms->lamps[k] = temp;
	}
}

void
lamplist_resize (struct lamplist *lms, int count)
{
	lms->count = count;
}

void
lamplist_keep_every (struct lamplist *lms, int count)
{
	lms->count /= count;
}

void
lamplist_output (struct lamplist *lms, const char *name)
{
	int i;

	printf ("#define %s ", name);
	for (i=0; i < lms->count; i++)
		printf ("%d%c", 
			lms->lamps[i],
			(i == lms->count - 1) ? ' ' : ',');
	printf ("\n");
}

int
main (int argc, char *argv[])
{
	struct lamplist *lms;
	const U8 temp[] = { LMSET_AMODE_ALL };
	int argn = 1;
	const char *outname = "LMS_AUTOGENERATED";
	
	/* Allocate and initialize a lamplist with an array of lamp values. */
	lms = lamplist_allocate ();
	lamplist_fill (lms, temp, sizeof (temp));

	/* Parse command-line arguments to figure out what to do to it. */
	while (argn < argc)
	{
		switch (argv[argn][0])
		{
			case '-':
				switch (argv[argn][1])
				{
					case 'r':
						lamplist_randomize (lms, 1);
						break;

					case 'o':
						outname = argv[++argn];
						break;

					case 's':
						lamplist_resize (lms, strtoul (argv[++argn], NULL, 0));
						break;

					case 'e':
						lamplist_keep_every (lms, strtoul (argv[++argn], NULL, 0));
						break;
				}
				break;

			default:
				break;
		}
		argn++;
	}

	/* Output the lamplist */
	lamplist_output (lms, outname);
	return (0);
}

